package com.gin.kotlin.no_gay_alliance.activity

import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.widget.EditText
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.gin.kotlin.no_gay_alliance.R
import com.gin.kotlin.no_gay_alliance.adapter.ban.BanKeywordAdapter
import com.gin.kotlin.no_gay_alliance.adapter.ban.BanUserAdapter
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.kotlin.no_gay_alliance.argument.UserCenterArgument
import com.gin.kotlin.no_gay_alliance.base.AbstractBindingActivity
import com.gin.kotlin.no_gay_alliance.base.AlertDialogUtils
import com.gin.kotlin.no_gay_alliance.base.ClipboardUtils
import com.gin.kotlin.no_gay_alliance.base.InputMethodUtils
import com.gin.kotlin.no_gay_alliance.base.IntRangeTextWatcher
import com.gin.kotlin.no_gay_alliance.callback.RCallback
import com.gin.kotlin.no_gay_alliance.database.dao.BanKeywordDao
import com.gin.kotlin.no_gay_alliance.database.dao.BanUserDao
import com.gin.kotlin.no_gay_alliance.database.entity.BanKeyword
import com.gin.kotlin.no_gay_alliance.database.entity.BanUser
import com.gin.kotlin.no_gay_alliance.databinding.ActivityMoreBanConfigBinding
import com.gin.kotlin.no_gay_alliance.databinding.DialogBanUserBinding
import com.gin.kotlin.no_gay_alliance.model.MoyuConfigModel
import com.gin.kotlin.no_gay_alliance.model.UserDetailModel
import com.gin.kotlin.no_gay_alliance.provider.ngaphp.UserInfoProvider
import java.util.Base64


class MoreBanConfigActivity : AbstractBindingActivity<ActivityMoreBanConfigBinding>() {
    private lateinit var mapper: ObjectMapper
    private lateinit var banKeywordDao: BanKeywordDao
    private lateinit var banUserDao: BanUserDao
    private lateinit var banKeywordAdapter: BanKeywordAdapter
    private lateinit var banUserAdapter: BanUserAdapter

    override fun onCreate() {
        val b = this.b ?: return
        this.banUserAdapter = BanUserAdapter(this, handler!!)
        this.banKeywordAdapter = BanKeywordAdapter(this, handler!!)
        this.mapper = ObjectMapper().registerModules(JavaTimeModule()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

        b.recyclerViewBlockUser.adapter = banUserAdapter
        b.recyclerViewBlockKeyword.adapter = banKeywordAdapter
        b.swipeRefreshLayout.setOnRefreshListener { query() }

        this.banUserDao = App.INSTANCE.database.banUserDao()
        this.banKeywordDao = App.INSTANCE.database.banKeywordDao()

    }

    override fun handleIntent(intent: Intent) {
    }

    override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, menuInflater)
        menuInflater.inflate(R.menu.more_ban, menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.mi_add_user -> showDialogAddUser()
            R.id.mi_add_keyword -> showDialogAddKeyword()
            R.id.mi_import -> importConfig()
            R.id.mi_export -> exportConfig()
        }
        return super.onOptionsItemSelected(item)
    }

    /**
     * 弹窗添加关键字
     */
    private fun showDialogAddKeyword() {
        // 弹窗添加关键字
        val editText = EditText(this)
        editText.hint = "请输入关键字"
        editText.requestFocus()
        editText.selectAll()

        AlertDialogUtils.builder(this, "添加屏蔽词", contentView = editText, listener = { _, which ->
            if (which == DialogInterface.BUTTON_POSITIVE) {
                val keyword = editText.text.toString().trim()
                if (keyword.isEmpty()) toast("屏蔽词不能为空") else {
                    val entity = BanKeyword(keyword)
                    banKeywordDao.add(listOf(entity))
                    banKeywordAdapter.pushData(entity)
                }
            }
        }).show()

        uiDelayed(200) { InputMethodUtils.show(editText, this) }
    }

    /**
     * 弹窗添加用户
     */
    private fun showDialogAddUser() {
        val binding = DialogBanUserBinding.inflate(LayoutInflater.from(this))

        binding.etUserId.addTextChangedListener(IntRangeTextWatcher(binding.etUserId, 1))
        binding.etUserId.requestFocus()
        binding.etUserId.selectAll()

        AlertDialogUtils.builder(this, "添加屏蔽用户", contentView = binding.root, listener = { _, which ->
            if (which == DialogInterface.BUTTON_POSITIVE) {
                val userId = binding.etUserId.text.toString().toLongOrNull()
                val username = binding.etUsername.text.toString().takeIf { it.isNotEmpty() }
                val remark = binding.etRemark.text.toString()

                // 查询用户信息
                UserInfoProvider.getInstance().enqueue(UserCenterArgument(userId, username, true), callback = object : RCallback<UserDetailModel, UserCenterArgument> {
                    override fun onSuccess(data: UserDetailModel, ignoreCache: Boolean) {
                        val banUser = BanUser(userId = data.userId!!, username = data.username, remark = remark)
                        banUserDao.add(listOf(banUser))
                        banUserAdapter.pushData(banUser)
                    }

                    override fun onError(errorMessage: String) {
                        toastLong(errorMessage)
                    }
                })

            }
        }).show()

        uiDelayed(200) { InputMethodUtils.show(binding.etUserId, this) }
    }

    /**
     * 导出配置到剪贴板
     */
    private fun exportConfig() {
        val config = MoyuConfigModel(banKeywords = banKeywordDao.list(), banUsers = banUserDao.list())
        val json = mapper.writeValueAsString(config)
        val base64 = String(Base64.getEncoder().encode(json.toByteArray()))
        ClipboardUtils.setText(base64, this)
        toast("已复制到剪贴板")
    }

    /**
     * 弹窗，从字符串中导入配置
     */
    private fun importConfig() {
        val text = ClipboardUtils.getText(0, this)
        if (text.isNullOrEmpty()) {
            toast("剪贴板为空")
            return
        }
        try {
            val json = String(Base64.getDecoder().decode(text))
            val config = mapper.readValue(json, MoyuConfigModel::class.java)
            if (config.banUsers.isNullOrEmpty() && config.banKeywords.isNullOrEmpty()) {
                toast("配置中不包含屏蔽词或用户")
                return
            }
            config.banUsers?.also { banUserDao.add(it) }
            config.banKeywords?.map { BanKeyword(it) }?.also { banKeywordDao.add(it) }
            toast("已添加 ${config.banKeywords?.size ?: 0} 个屏蔽词, ${config.banUsers?.size ?: 0} 个屏蔽用户")

            query()
        } catch (e: IllegalArgumentException) {
            AlertDialogUtils.builder(this, title = "导入失败", "无法识别的数据").show()
        } catch (e: Exception) {
            AlertDialogUtils.builder(this, title = "导入失败", "${e.localizedMessage}").show()
        }
    }

    override fun onResume() {
        super.onResume()
        query()
        setToolbarTitle("额外屏蔽 - 配置")
    }

    /**
     * 查询配置
     */
    private fun query() {
        b?.swipeRefreshLayout?.isRefreshing = true
        this.banUserAdapter.replaceData(banUserDao.list())
        this.banKeywordAdapter.replaceData(banKeywordDao.list())
        b?.swipeRefreshLayout?.isRefreshing = false
    }

    companion object {
        @JvmStatic
        fun start(context: Context) {
            val starter = Intent(context, MoreBanConfigActivity::class.java)
            context.startActivity(starter)
        }
    }
}